<template>
  <div class="app-container">
    <div class="content-container">
      <div class="layout-container">
        <!-- 左侧内容 -->
        <div class="left-panel">
          <div class="section-group">
            <div class="section-title">*知识库名称</div>
            <el-input
              v-model="configForm.name"
              placeholder="请输入知识库名称"
            />

            <!-- <div class="section-title">知识库图片</div> -->
            <!-- <div class="upload-area">
              <div class="image-preview" v-if="configForm.avatar">
                <img :src="configForm.avatar" alt="知识库图片" />
              </div>
              <div class="upload-btn">
                <image-upload
                  @success="handleAvatarSuccess"
                  @error="handleUploadError"
                  :limit="1"
                  :file-size="2"
                  :show-file-list="false"
                  :action="uploadUrl"
                  :headers="headers"
                  :accept="'image/jpeg,image/png,image/gif'"
                  :crop="true"
                  :preview="true"
                >
                  <template #default>
                    <el-button type="primary" plain>
                      <el-icon><Plus /></el-icon>
                      上传
                    </el-button>
                  </template>
                  <template #tip>
                    <div class="upload-tip">支持jpg、png格式，最大2MB</div>
                  </template>
                </image-upload>
              </div>
            </div> -->

            <div class="section-title">描述</div>
            <el-input
              v-model="configForm.description"
              placeholder="请输入描述"
            />

            <!-- <div class="section-title">权限</div>
            <el-button icon="User" size="small"> 权限 </el-button> -->
            <div class="section-box">
              <div class="section-title">
                PDF解析器
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      使用视觉模型进行 PDF 布局分析，以更好地识别文档结构，找到标题、文本块、图像和表格的位置。 如果选择 Naive 选项，则只能获取 PDF 的纯文本。请注意该功能只适用于 PDF 文档，对其他文档不生效。
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
              </div>
              <el-select
                v-model="configForm.parser_config.layout_recognize"
                placeholder="请选择"
                class="full-width"
              >
                <el-option
                  v-for="(item, index) in configList.layout_recognize"
                  :key="index"
                  :label="item"
                  :value="item"
                />
              </el-select>
              <div class="section-title">*切片方法  <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                        说明位于右侧
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip></div>
              <el-select
                v-model="configForm.chunk_method"
                placeholder="请选择"
                class="full-width"
              >
                <el-option
                  v-for="(item, index) in configList.chunk_method"
                  :key="index"
                  :label="item"
                  :value="item"
                />
              </el-select>

              <div class="section-title">建议文本块大小</div>
              <div class="slider-with-input">
                <el-slider
                  v-model="configForm.parser_config.chunk_token_num"
                  :min="0"
                  :max="1024"
                  :step="1"
                />
                <el-input-number
                  v-model="configForm.parser_config.chunk_token_num"
                  controls-position="right"
                  class="num-input"
                />
              </div>

              <div class="section-title">*文本分段标识符
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                        支持多字符作为分隔符，多字符用两个反引号 \`\` 分隔符包裹。若配置成：\n`##`; 系统将首先使用换行符、两个#号以及分号先对文本进行分割，随后再对分得的小文本块按照「建议文本块大小」设定的大小进行拼装。在设置文本分段标识符前请确保理解上述文本分段切片机制。
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
              </div>
              <el-input
                v-model="configForm.parser_config.delimiter"
                placeholder="\n"
              />
            </div>

            <!-- <div class="section-title">*访问模型</div>
            <el-select
              v-model="configForm.access_model"
              placeholder="请选择"
              class="full-width"
            >
              <el-option
                label="BAA/bge-large-zh-v1.5@BAAI"
                value="BAA/bge-large-zh-v1.5@BAAI"
              />
            </el-select> -->
            <div class="section-box">
              <div class="section-title">页面排名
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{ '知识库检索时，你可以为特定知识库设置较高的 PageRank 分数，该知识库中匹配文本块的混合相似度得分会自动叠加 PageRank 分数，从而提升排序权重。详见 https://ragflow.io/docs/dev/set_page_rank。'}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>

                </el-tooltip>
              </div>
              <div class="slider-with-input">
                <el-slider
                  v-model="configForm.pagerank"
                  :min="0"
                  :max="100"
                  :step="1"
                />
                <el-input-number
                  v-model="configForm.pagerank"
                  controls-position="right"
                  class="num-input"
                />
              </div>
              <div class="section-title">自动关键词提取

                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{ '自动为每个文本块中提取 N 个关键词，用以提升查询精度。请注意：该功能采用“系统模型设置”中设置的默认聊天模型提取关键词，因此也会产生更多 Token 消耗。另外，你也可以手动更新生成的关键词。'}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>

                </el-tooltip>
              </div>
              <div class="slider-with-input">
                <el-slider
                  v-model="configForm.parser_config.auto_keywords"
                  :min="0"
                  :max="20"
                  :step="1"
                />
                <el-input-number
                  v-model="configForm.parser_config.auto_keywords"
                  controls-position="right"
                  class="num-input"
                />
              </div>

              <div class="section-title">自动问题提取
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{`利用“系统模型设置”中设置的 chat model 对知识库的每个文本块提取 N 个问题以提高其排名得分。请注意，开启后将消耗额外的 token。您可以在块列表中查看、编辑结果。如果自动问题提取发生错误，不会妨碍整个分块过程，只会将空结果添加到原始文本块。`}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
              </div>
              <div class="slider-with-input">
                <el-slider
                  v-model="configForm.parser_config.auto_questions"
                  :min="0"
                  :max="10"
                  :step="1"
                  size="small"
                />
                <el-input-number
                  v-model="configForm.parser_config.auto_questions"
                  controls-position="right"
                  class="num-input"
                />
              </div>

              <div class="section-title">表格解析HTML
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{ '与 General 切片方法配合使用。未开启状态下，表格文件（XLSX、XLS（Excel97~2003））会按行解析为键值对。开启后，表格文件会被解析为 HTML 表格。若原始表格超过 12 行，系统会自动按每 12 行拆分为多个 HTML 表格。'}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
              </div>
              <el-switch v-model="configForm.parser_config.html4excel" />
            </div>

            <!-- <div class="section-title">标签集</div>
            <el-select
              v-model="configForm.parser_config.tag_set"
              placeholder="请选择"
              class="full-width"
            >
              <el-option label="通用版" value="general" />
            </el-select> -->

            <div class="section-box">
              <div class="section-title">使用召回增强RAPTOR策略

                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{ '为多跳问答任务启用 RAPTOR，详情请见 : https://ragflow.io/docs/dev/enable_raptor。'}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
              </div>
              <el-switch
                v-model="configForm.parser_config.raptor.use_raptor"
                @change="handleRaptorChange"
              />

              <div v-if="configForm.parser_config.raptor.use_raptor">
                <div class="section-title">*提示词
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ `'系统提示为大模型提供任务描述、规定回复方式，以及设置其他各种要求。系统提示通常与 key （变量）合用，通过变量设置大模型的输入数据。你可以通过斜杠或者 (x) 按钮显示可用的 key。`}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>
                  </el-tooltip>
                </div>
                <el-input
                  type="textarea"
                  v-model="configForm.parser_config.raptor.prompt"
                  :rows="3"
                  placeholder="请点击以下配置，小心数字，不要换行，配置如下：</br>{cluster_content}</br>以上都是自动采集处理的内容。"
                />

                <div class="section-title">最大Token数
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ '用于设定每个被总结的文本块的最大 token 数。'}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>
                  </el-tooltip>
                </div>
                <div class="slider-with-input">
                  <el-slider
                    v-model="configForm.parser_config.raptor.max_token"
                    :min="0"
                    :max="512"
                    :step="1"
                  />
                  <el-input-number
                    v-model="configForm.parser_config.raptor.max_token"
                    controls-position="right"
                    class="num-input"
                  />
                </div>

                <div class="section-title">阈值
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ '在 RAPTOR 中，数据块会根据它们的语义相似性进行聚类。阈值设定了数据块被分到同一组所需的最小相似度。阈值越高，每个聚类中的数据块越少；阈值越低，则每个聚类中的数据块越多。'}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>
                  </el-tooltip>
                </div>
                <div class="slider-with-input">
                  <el-slider
                    v-model="configForm.parser_config.raptor.threshold"
                    :min="0"
                    :max="1"
                    :step="0.01"
                  />
                  <el-input-number
                    v-model="configForm.parser_config.raptor.threshold"
                    :min="0"
                    :max="1"
                    :step="0.01"
                    controls-position="right"
                    class="num-input"
                  />
                </div>

                <div class="section-title">最大聚类数
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ '最大可设置的聚类数。'}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>
                  </el-tooltip>
                </div>
                <div class="slider-with-input">
                  <el-slider
                    v-model="configForm.parser_config.raptor.max_cluster"
                    :min="0"
                    :max="100"
                    :step="1"
                  />
                  <el-input-number
                    v-model="configForm.parser_config.raptor.max_cluster"
                    controls-position="right"
                    class="num-input"
                  />
                </div>
              </div>
            </div>

            <div class="section-box">
              <div class="section-title">提取知识图谱
                <el-tooltip
                  placement="top"
                  effect="dark"
                  popper-class="custom-dark-tooltip"
                >
                  <template #content>
                    <div class="width-300">
                      {{ '基于知识库内所有切好的文本块构建知识图谱，用以提升多跳和复杂问题回答的正确率。请注意：构建知识图谱将消耗大量 token 和时间。详见 https://ragflow.io/docs/dev/construct_knowledge_graph。'}}
                    </div>
                  </template>
                  <el-icon class="question-icon"><QuestionFilled /></el-icon>
                </el-tooltip> 
              </div>
              <el-switch
                v-model="configForm.parser_config.graphrag.use_graphrag"
                @change="handleGraphragChange"
              />
              <div v-show="configForm.parser_config.graphrag.use_graphrag">
                <div class="section-title">*实体类型</div>
                <div class="entity-types">
                  <el-tag
                    v-for="(tag, index) in configForm.parser_config?.graphrag
                      ?.entity_types"
                    :key="index"
                    closable
                    @close="removeEntityType(index)"
                    >{{ tag }}</el-tag
                  >
                  <el-input
                    v-if="inputVisible"
                    ref="InputRef"
                    v-model="inputValue"
                    class="w-20"
                    size="small"
                    @keyup.enter="handleInputConfirm"
                    @blur="handleInputConfirm"
                  />
                  <el-button
                    class="add-button"
                    type="primary"
                    icon="Plus"
                    size="small"
                    plain
                    @click="showInput"
                  ></el-button>
                </div>

                <div class="section-title">方法
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{`'Light：实体和关系提取提示来自 GitHub - HKUDS/LightRAG：“LightRAG：简单快速的检索增强生成”<br>
General：实体和关系提取提示来自 GitHub - microsoft/graphrag：基于图的模块化检索增强生成 (RAG) 系统'`}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>

                  </el-tooltip>
                </div>
                <el-select
                  v-model="configForm.parser_config.graphrag.method"
                  placeholder="请选择"
                  class="full-width"
                >
                  <el-option
                    v-for="(item, index) in configList.graphrag_method"
                    :key="index"
                    :label="item"
                    :value="item"
                  />
                </el-select>

                <div class="section-title">实体归一化
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ `解析过程会将具有相同含义的实体合并在一起，从而使知识图谱更简洁、更准确。应合并以下实体：特朗普总统、唐纳德·特朗普、唐纳德·J·特朗普、唐纳德·约翰·特朗普`}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>

                  </el-tooltip>
                </div>
                <el-switch
                  v-if="
                    configForm.parser_config &&
                    configForm.parser_config.graphrag
                  "
                  v-model="configForm.parser_config.graphrag.resolution"
                />

                <div class="section-title">社区检测生成
                  <el-tooltip
                    placement="top"
                    effect="dark"
                    popper-class="custom-dark-tooltip"
                  >
                    <template #content>
                      <div class="width-300">
                        {{ '区块被聚集成层次化的社区，实体和关系通过更高抽象层次将每个部分连接起来。然后，我们使用 LLM 生成每个社区的摘要，称为社区报告。更多信息：https://www.microsoft.com/en-us/research/blog/graphrag-improving-global-search-via-dynamic-community-selection/'}}
                      </div>
                    </template>
                    <el-icon class="question-icon"><QuestionFilled /></el-icon>
                  </el-tooltip>
                </div>
                <el-switch
                  v-if="
                    configForm.parser_config &&
                    configForm.parser_config.graphrag
                  "
                  v-model="configForm.parser_config.graphrag.community"
                />
              </div>
            </div>
            <!-- 按钮区 -->
            <div class="button-group">
              <el-button>取消</el-button>
              <el-button type="primary" @click="saveConfig">保存</el-button>
            </div>
          </div>
        </div>

        <!-- 右侧内容 -->
        <div class="right-panel">
          <div class="section-group">
            <div class="method-title">
              {{ configForm.chunk_method }} 分块方法说明
            </div>
            <div class="method-desc" v-html="getChunkMethodDescription()"></div>
            <!-- <div class="method-desc">
              支持的文件格式包括DOCX、XLSX、XLS
              (Excel97-2003)、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF、CSV、JSON、EML、HTML。
              <p>此方法适用的分类场景有：</p>
              <ul>
                <li>系统使用预设规则将文档划分成若干个片段。</li>
                <li>
                  基于策略，这些文档的内容会用Token数不超过Token数上限的方式。
                </li>
              </ul>
            </div> -->

            <div class="method-title">{{ configForm.chunk_method }} 示例</div>
            <!-- {{'@/assets/images/chunk-method/book-01.svg'}} -->
            <!-- <img src="@/assets/images/chunk-method/book-01.svg" alt="示例1" /> -->
            <div class="method-desc" v-if="imageList.length > 0">
              提供以下示例：
            </div>
            <div class="example-images" v-if="imageList.length > 0">
              <div
                style="width: 200px"
                class="example-image"
                v-for="(imagePath, index) in imageList"
                :key="imagePath"
              >
                <img
                  :src="getImageUrl(imagePath)"
                  :alt="`${configForm.chunk_method || 'naive'} 示例 ${
                    index + 1
                  }`"
                />
                <!-- <div class="example-caption">{{ getImageCaption(index) }}</div> -->
              </div>
            </div>
            <!-- <div class="method-title">General 对话示例</div> -->

            <!-- <div class="method-desc" v-if="showExamples" >提供以下两种形式示例：</div> -->
            <!-- <div class="example-images" v-if="showExamples">
              <div class="example-image">
                <img src="@/assets/images/p1.svg" alt="示例1" />
                <div class="example-caption">Step 1: Split into pieces.</div>
              </div>
              <div class="example-image">
                <img src="@/assets/images/p2.svg" alt="示例2" />
                <div class="example-caption">Step 2: Merge into a chunk.</div>
              </div>
            </div> -->

            <!-- <div class="method-title">General 对话示例</div> -->
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, nextTick } from "vue";
import { Plus, Delete, User, QuestionFilled } from "@element-plus/icons-vue";
import { updateData, getConfig, getConfigList } from "@/api/knowledge/dataset";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
const ids = JSON.parse(localStorage.getItem("ids"));
console.log(ids, "ids");
const dataset_id = ref();
const configList = ref([]);
const inputValue = ref("");
// const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])
const inputVisible = ref(false);
const InputRef = ref(null);
// 表单数据
const configForm = ref({
  name: "", // 知识库名称
  avatar: "", // 知识库图片
  description: "", // 描述
  pagerank: 5, // 页面排序
  // embedding_model: "", // 嵌入模型
  chunk_method: "", // 切片方法
  access_model: "", // 访问模型
  parser_config: {
    method: "",
    layout_recognize: "",
    delimiter: "\n",
    chunk_token_num: 1,
    auto_keywords: 5,
    auto_questions: 5,
    html4excel: true,
    task_page_size: 1,
    layout_recognize: "",
    max_token: 256,
    threshold: 0.1,
    max_size: 64,
    tag_set: "",
    prompt: "",
    raptor: {
      use_raptor: false,
    },
    graphrag: {
      community: false,
      entity_types: [],
      method: "",
      resolution: false,
      use_graphrag: false,
    },
  },
});
if (ids) {
  dataset_id.value = ids.dataset_id;
}
if (localStorage.getItem("dataset_id")) {
  dataset_id.value = JSON.parse(localStorage.getItem("dataset_id"));
}
onMounted(() => {
  findConfig();
  getConfigList().then((res) => {
    configList.value = res.data;
    configForm.value.parser_config.graphrag.entity_types =
      configForm.value.parser_config.graphrag.entity_types.length > 0
        ? configForm.value.parser_config.graphrag.entity_types
        : [
            "organization",
            "person",
            "geo",
            "event",
            "category",
          ];
  });
});
// 描述
const descriptionobj = ref({
  graphragTip: `知识图谱生成时，你可以为特定知识库设置较高的 PageRank 分数，该知识库中匹配文本块的混合相似度得分会自动叠加 PageRank 分数，从而提升排序权重。详见 https://ragflow.io/docs/dev/set_page_rank。`,
  pageRankTip: `知识库检索时，你可以为特定知识库设置较高的 PageRank 分数，该知识库中匹配文本块的混合相似度得分会自动叠加 PageRank 分数，从而提升排序权重。详见 https://ragflow.io/docs/dev/set_page_rank。`,
});
const pageRankTip = `知识库检索时，你可以为特定知识库设置较高的 PageRank 分数，该知识库中匹配文本块的混合相似度得分会自动叠加 PageRank 分数，从而提升排序权重。详见 https://ragflow.io/docs/dev/set_page_rank。`
// 切片方法描述映射
const chunkMethodDescriptions = {
  book: `<p>支持的文件格式为<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。</p><p>
      由于一本书很长，并不是所有部分都有用，如果是 PDF，
      请为每本书设置<i>页面范围</i>，以消除负面影响并节省分析计算时间。</p>`,
  laws: `<p>支持的文件格式为<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。</p><p>
      法律文件有非常严格的书写格式。 我们使用文本特征来检测分割点。
      </p><p>
      chunk的粒度与'ARTICLE'一致，所有上层文本都会包含在chunk中。
      </p>`,
  manual: `<p>仅支持<b>PDF</b>。</p><p>
      我们假设手册具有分层部分结构。 我们使用最低的部分标题作为对文档进行切片的枢轴。
      因此，同一部分中的图和表不会被分割，并且块大小可能会很大。
      </p>`,
  naive: `<p>支持的文件格式为<b>DOCX、XLSX、XLS (Excel 97-2003)、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF、CSV、JSON、EML、HTML</b>。</p>
      <p>此方法将简单的方法应用于块文件：</p>
      <p>
      <li>系统将使用视觉检测模型将连续文本分割成多个片段。</li>
      <li>接下来，这些连续的片段被合并成Token数不超过"Token数"的块。</li></p>`,
  paper: `<p>仅支持<b>PDF</b>文件。</p><p>
      如果我们的模型运行良好，论文将按其部分进行切片，例如<i>摘要、1.1、1.2</i>等。</p><p>
      这样做的好处是LLM可以更好的概括论文中相关章节的内容，
      产生更全面的答案，帮助读者更好地理解论文。
      缺点是它增加了 LLM 对话的背景并增加了计算成本，
      所以在对话过程中，你可以考虑减少'<b>topN</b>'的设置。</p>`,
  presentation: `<p>支持的文件格式为<b>PDF</b>、<b>PPTX</b>。</p><p>
      每个页面都将被视为一个块。 并且每个页面的缩略图都会被存储。</p><p>
      <i>您上传的所有PPT文件都会使用此方法自动分块，无需为每个PPT文件进行设置。</i></p>`,
  qa: ` <p>
      此块方法支持<b> excel </b>和<b> csv/txt </b>文件格式。
    </p>
    <li>
      如果文件是<b> excel </b>格式，则应由两个列组成
      没有标题：一个提出问题，另一个用于答案，
      答案列之前的问题列。多张纸是
      只要列正确结构，就可以接受。
    </li>
    <li>
      如果文件是<b> csv/txt </b>格式
      以 UTF-8 编码且用 TAB 作分开问题和答案的定界符。
    </li>
    <p>
      <i>
        未能遵循上述规则的文本行将被忽略，并且
        每个问答对将被认为是一个独特的部分。
      </i>
    </p>`,
  resume: `<p>支持的文件格式为<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。
      </p><p>
      简历有多种格式，就像一个人的个性一样，但我们经常必须将它们组织成结构化数据，以便于搜索。
      </p><p>
      我们不是将简历分块，而是将简历解析为结构化数据。 作为HR，你可以扔掉所有的简历，
      您只需与<i>'RAGFlow'</i>交谈即可列出所有符合资格的候选人。
      </p>`,
  table: `<p><b>XLSX</b>和<b>CSV/TXT</b>格式文件。</p><p>
      以下是一些提示：
      <ul>
    <li>对于 csv 或 txt 文件，列之间的分隔符为 <em><b>TAB</b></em>。</li>
    <li>第一行必须是列标题。</li>
    <li>列标题必须是有意义的术语，以便我们的大语言模型能够理解。
    列举一些同义词时最好使用斜杠<i>'/'</i>来分隔，甚至更好
    使用方括号枚举值，例如 <i>'gender/sex(male,female)'</i>.<p>
    以下是标题的一些示例：<ol>
        <li>供应商/供货商<b>'TAB'</b>颜色（黄色、红色、棕色）<b>'TAB'</b>性别（男、女）<b>'TAB'</ b>尺码（M、L、XL、XXL）</li>
        <li>姓名/名字<b>'TAB'</b>电话/手机/微信<b>'TAB'</b>最高学历（高中，职高，硕士，本科，博士，初中，中技，中 专，专科，专升本，MPA，MBA，EMBA）</li>
        </ol>
        </p>
    </li>
    <li>表中的每一行都将被视为一个块。</li>
    </ul>`,
  picture: `
      <p>支持图像文件。 视频即将推出。</p><p>
      如果图片中有文字，则应用 OCR 提取文字作为其文字描述。
      </p><p>
      如果OCR提取的文本不够，可以使用视觉LLM来获取描述。
      </p>`,
  one: `
      <p>支持的文件格式为<b>DOCX、EXCEL、PDF、TXT</b>。
      </p><p>
      对于一个文档，它将被视为一个完整的块，根本不会被分割。
      </p><p>
      如果你要总结的东西需要一篇文章的全部上下文，并且所选LLM的上下文长度覆盖了文档长度，你可以尝试这种方法。
      </p>`,
  knowledgeGraph: `<p>支持的文件格式为<b>DOCX、EXCEL、PPT、IMAGE、PDF、TXT、MD、JSON、EML</b>

<p>文件分块后，使用分块提取整个文档的知识图谱和思维导图。此方法将简单的方法应用于分块文件：
连续的文本将被切成大约 512 个 token 数的块。</p>
<p>接下来，将分块传输到 LLM 以提取知识图谱和思维导图的节点和关系。</p>

注意您需要指定的条目类型。</p>`,
  tag: `<p>使用"Tag"分块方法的知识库用作标签集.其他知识库可以把标签集当中的标签按照相似度匹配到自己对应的文本块中，对这些知识库的查询也将根据此标签集对自己进行标记。</p>
<p>使用"标签"作为分块方法的知识库<b>不</b>参与 RAG 检索过程。</p>
<p>标签集中的每个文本分块是都是相互独立的标签和标签描述的文本对。</p>

<p>Tag 分块方法支持<b>XLSX</b>和<b>CSV/TXT</b>文件格式。</p>
<p>如果文件为<b>XLSX</b>格式，则它应该包含两列无标题：一列用于标签描述，另一列用于标签，标签描述列位于标签列之前。支持多个工作表，只要列结构正确即可。</p>
<p>如果文件为 <b>CSV/TXT</b> 格式，则必须使用 UTF-8 编码并以 TAB 作为分隔符来分隔内容和标签。</p>
<p>在标签列中，标签之间使用英文逗号分隔。</p>
<i>不符合上述规则的文本行将被忽略。</i>
`,
};

// 默认描述（当找不到对应切片方法的描述时使用）
const defaultDescription = `<p>支持的文件格式包括DOCX、XLSX、XLS
(Excel97-2003)、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF、CSV、JSON、EML、HTML。</p>
<p>此方法适用的分类场景有：</p>
<ul>
  <li>系统使用预设规则将文档划分成若干个片段。</li>
  <li>基于策略，这些文档的内容会用Token数不超过Token数上限的方式。</li>
</ul>`;

// 获取当前切片方法的描述
const getChunkMethodDescription = () => {
  const method = configForm.value.chunk_method || "naive";
  return chunkMethodDescriptions[method] || defaultDescription;
};
// 使用召回增强RAPTOR策略
const handleRaptorChange = () => {
  console.log(configForm.value.parser_config.raptor.use_raptor, "raptor");
  if (configForm.value.parser_config.raptor.use_raptor) {
    configForm.value.parser_config.raptor = {
      max_cluster: configForm.value.parser_config.raptor.max_cluster || 64, // 最大聚类数
      max_token: configForm.value.parser_config.raptor.max_token || 256, // 最大token数
      prompt:
        configForm.value.parser_config.raptor.prompt ||
        `请总结以下段落。 小心数字，不要编造。 段落如下：
        {cluster_content}
 以上就是你需要总结的内容。`, // 提示词
      random_seed: configForm.value.parser_config.raptor.random_seed || 55, // 随机种子
      threshold: configForm.value.parser_config.raptor.threshold || 0.1, // 阈值
      use_raptor: configForm.value.parser_config.raptor.use_raptor || true, // 使用召回增强RAPTOR策略
    };
  } else {
    configForm.value.parser_config.raptor = {
      use_raptor: false,
      ...configForm.value.parser_config.raptor,
    };
  }
};
// 使用知识图谱
const handleGraphragChange = () => {
  console.log(configForm.value.parser_config.graphrag.use_graphrag, "graphrag");
  if (configForm.value.parser_config.graphrag.use_graphrag) {
    configForm.value.parser_config.graphrag = {
      use_graphrag: true,
      community: configForm.value.parser_config.graphrag.community || false,
      entity_types:
        configForm.value.parser_config.graphrag.entity_types.length > 0
          ? configForm.value.parser_config.graphrag.entity_types
          : [
              "organization",
              "person",
              "geo",
              "event",
              "category",
            ],
      method: configForm.value.parser_config.graphrag.method || "Light",
      resolution: configForm.value.parser_config.graphrag.resolution || false,
    };
  } else {
    configForm.value.parser_config.graphrag = {
      use_graphrag: false,
      ...configForm.value.parser_config.graphrag,
    };
  }
};
// 是否显示示例（某些切片方法可能不需要示例）
const showExamples = computed(() => {
  // 根据需要调整哪些切片方法需要显示示例
  const methodsWithExamples = ["naive", "book", "paper"];
  return methodsWithExamples.includes(configForm.value.chunk_method);
});

const currentMethodImages = ref([]);
const getImageUrl = (imagePath) => {
  return `/${imagePath}.svg`;
};

const getImageName = (prefix, length) =>
  new Array(length)
    .fill(0)
    .map((x, idx) => `chunk-method/${prefix}-0${idx + 1}`); //
console.log(getImageName("book", 4), "getImageName");
const ImageMap = {
  book: getImageName("book", 4),
  laws: getImageName("law", 2),
  manual: getImageName("manual", 4),
  picture: getImageName("media", 2),
  naive: getImageName("naive", 2),
  paper: getImageName("paper", 2),
  presentation: getImageName("presentation", 2),
  qa: getImageName("qa", 2),
  resume: getImageName("resume", 2),
  table: getImageName("table", 2),
  one: getImageName("one", 2),
  knowledge_graph: getImageName("knowledge-graph", 2),
  tag: getImageName("tag", 2),
};
const getImageNames = (method) => {
  return ImageMap[method] || [];
};
const imageList = computed(() => {
  if (configForm.value.chunk_method in ImageMap) {
    return ImageMap[configForm.value.chunk_method];
  }
  return [];
});
const showInput = () => {
  inputVisible.value = true;
  if (configForm.value.parser_config.graphrag.entity_types == null) {
    configForm.value.parser_config.graphrag.entity_types = [];
  }
  nextTick(() => {
    InputRef.value.input.focus();
  });
};

const handleInputConfirm = () => {
  if (inputValue.value) {
    console.log(
      configForm.value.parser_config.graphrag.entity_types,
      "inputValue"
    );

    configForm.value.parser_config.graphrag.entity_types.push(inputValue.value);
  }
  inputVisible.value = false;
  inputValue.value = "";
};
const findConfig = () => {
  getConfig({ dataset_id: dataset_id.value }).then((res) => {
    // 使用解构赋值直接获取需要的字段
    const {
      dataset_name,
      dataset_avatar,
      dataset_description,
      dataset_pagerank,
      dataset_chunk_method,
      dataset_access_model,
      parser_config,
    } = res.data;

    // 构建新的配置对象
    configForm.value = {
      ...res.data,
      // 替换字段名
      name: dataset_name,
      avatar: dataset_avatar,
      description: dataset_description,
      pagerank: dataset_pagerank,
      chunk_method: dataset_chunk_method,
      access_model: dataset_access_model,
      parser_config: {
        ...parser_config,
        // 确保 task_page_size 有值
        task_page_size: parser_config.task_page_size || 10,
        // 处理 graphrag 对象
        graphrag: {
          ...parser_config.graphrag,
          // 确保 entity_types 有值，如果为空则使用配置列表中的预设值
          entity_types:
            parser_config.graphrag?.entity_types.length > 0
              ? parser_config.graphrag.entity_types
              : [
                  "organization",
                  "person",
                  "geo",
                  "event",
                  "category",
                ],
          // 默认启用社区检测和实体归一化
        },
        // 确保 raptor 对象存在
        raptor: {
          ...parser_config.raptor,
          use_raptor: parser_config.raptor?.use_raptor || false,
        },
      },
    };

    console.log(configForm.value, "优化后的配置对象");
  });
};
const saveConfig = () => {
  const data = {
    ...configForm.value,
    dataset_id: dataset_id.value,
  };
  updateData(data).then((res) => {
    if (res.code == 200) {
      proxy.$modal.msgSuccess("保存成功");
      findConfig();
      // ElMessage.success("保存成功");
    } else {
      ElMessage.error("保存失败");
    }
  });
};
// 实体类型相关方法
function showEntityTypeInput() {
  // 实现添加实体类型的逻辑
}

function removeEntityType(index) {
  configForm.value.parser_config.graphrag.entity_types.splice(index, 1);
}

// 使用计算属性访问和设置嵌套属性
const graphragResolution = computed({
  get: () => {
    // 安全访问嵌套属性
    return configForm.value.parser_config?.graphrag?.resolution ?? false;
  },
  set: (value) => {
    // 安全设置嵌套属性
    if (!configForm.value.parser_config) {
      configForm.value.parser_config = {};
    }
    if (!configForm.value.parser_config.graphrag) {
      configForm.value.parser_config.graphrag = {
        use_graphrag: true,
        entity_types: [],
        method: "Light",
        community: false,
      };
    }
    configForm.value.parser_config.graphrag.resolution = value;
  },
});

function handleAvatarSuccess(res) {
  console.log("图片上传成功:", res);
  if (res.code === 200) {
    configForm.value.avatar = res.data.url || res.url || "";
    ElMessage.success("图片上传成功");
  } else {
    ElMessage.error(res.msg || "上传失败");
  }
}

function handleUploadError(error) {
  console.error("上传错误:", error);
  ElMessage.error("图片上传失败");
}
</script>

<style scoped>
.app-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 84px);
}

.content-container {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
}

.layout-container {
  display: flex;
  min-height: calc(100vh - 124px);
}

.left-panel {
  width: 50%;
  padding: 24px;
  border-right: 1px solid #ebeef5;
  overflow-y: auto;
}

.right-panel {
  width: 50%;
  padding: 24px;
  background-color: #fff;
  overflow-y: auto;
}

.section-group {
  margin-bottom: 20px;
}
.section-box {
  background-color: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  margin-top: 20px;
}
:deep(.el-slider__button-wrapper) {
  margin-left: 10px;
}
.section-title {
  margin: 20px 0 8px 0;
  font-weight: 500;
  font-size: 14px;
  color: #303133;
  display: flex;
  align-items: center;
}

.section-title:first-of-type {
  margin-top: 0;
}

.upload-area {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 8px;
}

.image-preview {
  width: 80px;
  height: 80px;
  border-radius: 4px;
  border: 1px dashed #d9d9d9;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.upload-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

.method-title {
  font-weight: bold;
  margin: 24px 0 12px 0;
  color: #303133;
}

.method-title:first-of-type {
  margin-top: 0;
}

.method-desc {
  color: #606266;
  line-height: 1.6;
  margin-bottom: 16px;
}

.method-desc :deep(p) {
  margin: 10px 0;
}

.method-desc :deep(b) {
  font-weight: 600;
  color: #303133;
}

.method-desc :deep(i) {
  font-style: italic;
  color: #606266;
}

.method-desc :deep(ul),
.method-desc :deep(ol) {
  padding-left: 20px;
  margin: 8px 0;
}

.method-desc :deep(li) {
  margin-bottom: 6px;
}

.example-images {
  display: flex;
  gap: 20px;
  margin: 16px 0 24px 0;
}

.example-image {
  flex: 1;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
}

.example-image img {
  width: 100%;
  height: auto;
  display: block;
}

.example-caption {
  padding: 8px;
  color: #606266;
  background: #fff;
  border-top: 1px solid #ebeef5;
  text-align: center;
}

.slider-with-input {
  display: flex;
  align-items: center;
  gap: 12px;
}

.slider-with-input .el-slider {
  flex: 1;
}

.num-input {
  width: 80px;
}

.entity-types {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.entity-types .el-tag {
  margin-bottom: 5px;
}

.button-group {
  display: flex;
  justify-content: flex-end;
  margin-top: 40px;
  gap: 12px;
}

.full-width {
  width: 100%;
}

.add-button {
  padding: 5px 10px;
  height: 24px;
  line-height: 24px;
  font-size: 12px;
}

.question-icon {
  font-size: 16px;
  color: #909399;
  margin-left: 5px;
  cursor: help;
  transition: color 0.3s;
}

.question-icon:hover {
  color: #409EFF;
}
.width-300 {
  max-width: 200px;
}
:deep(.custom-dark-tooltip) {
  max-width: 300px !important;
  line-height: 1.5 !important;
  padding: 8px 12px !important;
  background-color: rgba(0, 0, 0, 0.8) !important;
  color: #fff !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
}

:deep(.custom-dark-tooltip .el-popper__arrow::before) {
  background-color: rgba(0, 0, 0, 0.8) !important;
  border-color: transparent !important;
}
</style>
